/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Scenario.java
 *
 * Created on Oct 31, 2009, 12:11:28 PM
 */
package simulador;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author rangel
 */
public class Scenario extends javax.swing.JPanel implements Runnable {

	private Graphics2D g2d;
	private ArrayList<Bot> botList;
	private ArrayList<Bot> obstacleList;
	private ArrayList<RetaCarregada> lineList;
	private ArrayList<Bot> enemyList;
	public boolean isRunning = false;
	private long timeToSleep = 10;
	private boolean insertingGoal;
	public Goal currentGoal;
	private Goal agent = null;
	private boolean insertingBot = false;
	private boolean modifyingGrid = false;
	public Bot currentBot;
	public ArrayList<Bot> inimigos; // Utilizado pelo AStar
	private Torre currentTorre;
	private Bot currentObstacle;
	private boolean insertingObstacle = false;
	private boolean insertingEnemy = false;
	private boolean showRadar = true;
	private boolean insertingLine = false;
	private RetaCarregada currentLine;
	private boolean potentialFields = true;
	public boolean atractionBots = true;
	public int cellSpace = 35;
	public ArrayList<Atom> grid;
	private Color colorgrid = null;
	private float currentCost = 1;
	private AStar astar = new AStar();
	public boolean algAstar = false;
	public int enemiesToGo; // Contador de inimigos
	Point quadradoMouse = new Point();
	private float rotate = 0;
	private Controle parent;
	private boolean insertingTorre = false;
	private boolean insertingHeart = false;
	public ArrayList<Torre> listTorres;
	private int myLife = 10;
	public Heart heartPosition = null;
	int level = 0;
	int vidaInimigo = 100;
	private boolean chase;
	private boolean movingAgent;

	public void setMyLife(int myLife) {
		this.myLife = myLife;
	}

	public void setMyMoney(int myMoney) {
		this.myMoney = myMoney;
	}
	private int myMoney = 100;

	public void setParent(Controle c) {
		parent = c;
	}

	public void setAlgAstar(boolean algAstar) {
		this.algAstar = algAstar;
		if (currentGoal != null) {
			astar.setGoal((int) (currentGoal.getXPosition() / cellSpace), (int) (currentGoal.getYPosition() / cellSpace));
		}
	}

	public void setInsertingEnemy(boolean insertingEnemy) {
		this.insertingEnemy = insertingEnemy;
	}

	public void setInsertingHeart(boolean insertingHeart) {
		this.insertingHeart = insertingHeart;
	}
	
	public void setModifyingGrid(boolean modifyingGrid) {
		this.modifyingGrid = modifyingGrid;
	}

	public boolean  getAtractionBots() {
		return atractionBots;
	}
	public void setAtractionBots(boolean atractionBots) {
		this.atractionBots = atractionBots;
		for (int i = 0; i < botList.size(); i++) {
			Bot bot = botList.get(i);
			bot.setAtraction(atractionBots);
		}
	}

	public void setChase(boolean chase) {
		this.chase = chase;
	}
	
	public void setMovingAgent(boolean agent) {
		this.movingAgent = agent;
	}

	public void setPotentialFields(boolean potentialFields) {
		this.potentialFields = potentialFields;
	}

	/** Creates new form Scenario */
	public Scenario() {
		initComponents();
		botList = new ArrayList<Bot>();
		obstacleList = new ArrayList<Bot>();
		lineList = new ArrayList<RetaCarregada>();
		grid = new ArrayList<Atom>();
		enemyList = new ArrayList<Bot>();
		astar.setScenario(this);
		inimigos = new ArrayList<Bot>();
		listTorres = new ArrayList<Torre>();
	}

	public void addAgent(Goal mobileGoal) {
		agent = mobileGoal;
	}

	public void newSimulation() {
		botList.clear();
		lineList.clear();
		obstacleList.clear();
		grid.clear();
		for(int i=0;i<inimigos.size(); i++)
			inimigos.get(i).removeLabel();
		inimigos.clear();
		if(currentBot != null) currentBot.removeLabel();
		currentBot = null;
		if(currentGoal != null) currentGoal.removeLabel();
		currentGoal = null;
		if(currentObstacle != null) currentObstacle.removeLabel();
		currentObstacle = null;
		if(currentTorre != null) currentTorre.removeLabel();
		currentTorre = null;
		currentLine = null;

		if(heartPosition != null) heartPosition.removeLabel();
		heartPosition = null;

		setMovingAgent(false);
		agent = null;

		modifyingGrid = false;
		algAstar = false;
		potentialFields = true;
		chase = false;
		for(Iterator<Torre> it= listTorres.iterator(); it.hasNext();) {
			Torre t = it.next();
			for(Iterator<Bot> it2= t.listTiros.iterator(); it2.hasNext();) {
				it2.next().removeLabel();
			}
			t.listTiros.clear();
			t.removeLabel();
		}
		listTorres.clear();
		repaint();
		level = 0;
		vidaInimigo = 100;
	}

	public void addBot(Bot b) {
		if (currentGoal != null && potentialFields) {
			b.addGoal(currentGoal);
		} else if (chase) {
			b.addGoal(agent);
		}
		botList.add(b);
	}

	public void addObstacle(Bot b) {
		obstacleList.add(b);
	}

	public void setTimeToSleep(long time) {
		timeToSleep = time;
	}

	public void setInsertingGoal(boolean b) {
		insertingGoal = b;
	}

	public void setInsertingLine(boolean b) {
		insertingLine = b;
	}

	public void setTailSize(int size) {
		Goal.tailSize = size;
	}

	public void drawGrid() {
		g2d.setColor(new Color(0xcdcdcd));
		for (int i = 0; i <= this.getWidth(); i += cellSpace) {
			g2d.drawLine(i, 0, i, this.getHeight());
			for (int j = 0; j <= this.getHeight(); j += cellSpace) {
				g2d.drawLine(0, j, this.getWidth(), j);
			}
		}
	}

	public void drawImage(String image, int x, int y, float rotate) {

		BufferedImage img = null;
		try {
			img = ImageIO.read(new File(image));
		} catch (IOException ex) {
			Logger.getLogger(Scenario.class.getName()).log(Level.SEVERE, null, ex);
		}
		int w = img.getWidth(null);
		int h = img.getHeight(null);
		//BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
		AffineTransform origXform = g2d.getTransform();
		AffineTransform newXform = (AffineTransform) (origXform.clone());

		// Ajustando eixo de rotação
		int xRot = x + img.getWidth(this) / 2;
		int yRot = y + img.getHeight(this) / 2;
		newXform.rotate(Math.toRadians(rotate), xRot, yRot);
		g2d.setTransform(newXform);

		g2d.drawImage(img, x, y, this);
		g2d.setTransform(origXform); // Volta o eixo ao estado original

	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (enemiesToGo > 0 && currentBot != null) {
			if (inimigos.size() == 0) {
				Bot inimigo = new Bot(new Point((int) currentBot.xPosition, (int) currentBot.yPosition), 35, 35, "bot", false, this, vidaInimigo, currentBot.getImagePath());
				astar.setCurrentPos((int) (inimigo.xPosition / cellSpace), (int) (inimigo.yPosition / cellSpace));
				inimigo.setBestPath(astar.bestPath());
				inimigos.add(0, inimigo);
				enemiesToGo--;
			} else {
				Bot en = inimigos.get(0);
				int xDif = Math.abs((int) (en.xPosition - currentBot.xPosition) / cellSpace);
				int yDif = Math.abs((int) (en.yPosition - currentBot.yPosition) / cellSpace);
				if (xDif > 1 || yDif > 1) {
					Bot inimigo = new Bot(new Point((int) currentBot.xPosition, (int) currentBot.yPosition), 35, 35, "bot", false, this, vidaInimigo, currentBot.getImagePath());
					astar.setCurrentPos((int) (inimigo.xPosition / cellSpace), (int) (inimigo.yPosition / cellSpace));
					inimigo.setBestPath(astar.bestPath());
					inimigos.add(0, inimigo);
					enemiesToGo--;
				}
			}
		}
		g2d = (Graphics2D) g;
		g2d.setColor(Color.blue);
		rotate = (rotate + 1) % 360;
		drawObstacles();
		drawPesosGrid();
		drawGrid();
		drawGoals();
		drawLines();
		drawBots();
		drawPosMouse();
		drawTorres();
		//if(algAstar && heartPosition != null) heartPosition.draw(g2d);
		//drawEnemies();
		if (currentGoal != null && algAstar && isRunning) {
			moveBotPositionPath();
		}
		if (currentLine != null) {
			currentLine.draw(g2d);
		}
		if (chase && agent != null) {
			agent.updatePosition();
			agent.draw(g2d, showRadar);
		}

	}

	public void setInsertingTorre(boolean selected) {
		insertingTorre = selected;
	}

	private void defineObstacle() {
		int xInit = (int) currentObstacle.xPosition - (int) currentObstacle.getRadius();
		int yInit = (int) currentObstacle.yPosition - (int) currentObstacle.getRadius();

		int range = (int) (2 * currentObstacle.getRadius()) / cellSpace;
		for (int i = xInit / cellSpace; i < xInit / cellSpace + range + 2; i++) {
			for (int j = yInit / cellSpace; j < yInit / cellSpace + range + 2; j++) {
				Atom a = new Atom(Color.black, new Point(i, j), Float.POSITIVE_INFINITY);
				grid.add(a);
			}
		}
	}

	private void drawTorres() {

		for (int i = 0; i < listTorres.size(); i++) {
			Torre torre = listTorres.get(i);
			//torre.draw(g2d);
			if (isRunning && algAstar) {
				torre.atira(inimigos, g2d);
			}
		}

/*		if (myMoney > 0 && currentTorre != null && !isRunning) {
			currentTorre.draw(g2d);
		}*/
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                formMouseReleased(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                formMouseMoved(evt);
            }
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 488, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 409, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

		private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
			// TODO add your handling code here:
			if (insertingGoal) {
				if (algAstar) {
					if(currentGoal==null) {
						currentGoal = new Goal(new Point(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2),
								30, 30, "goal", cellSpace, this, "/images/Peach.gif");
						if (currentBot != null && currentBot.xPosition >= currentGoal.xPosition) {
							currentBot.changeImage("/images/Tartaruga-avoadoreE.gif");
						} else if (currentBot != null) {
							currentBot.changeImage("/images/Tartaruga-avoadoreD.gif");
						}
					}
					else
					{
						currentGoal.updatePosition(new Point(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2));
						if (currentBot != null && currentBot.xPosition >= currentGoal.xPosition) {
							currentBot.changeImage("/images/Tartaruga-avoadoreE.gif");
						} else if (currentBot != null) {
							currentBot.changeImage("/images/Tartaruga-avoadoreD.gif");
						}
					}
				} else {
					if(currentGoal == null)
						currentGoal = new Goal(evt.getPoint(), 30, 30, "goal", cellSpace, this, null);
					else {
						currentGoal.xPosition = evt.getX();
						currentGoal.yPosition = evt.getY();
					}
				}
				if (currentBot != null && heartPosition != null) {
					parent.buttonStart().setEnabled(true);
					if (algAstar) {
						parent.menuItemSave().setEnabled(true);
					}
				}
			} else if (insertingBot) {
				if (algAstar && currentBot == null) {
					if (currentGoal != null && evt.getX() >= currentGoal.xPosition) {
						currentBot = new Bot(evt.getPoint(), 35, 35, "bot", atractionBots, this, 10, "/images/Tartaruga-avoadoreE.gif");
					} else {
						currentBot = new Bot(evt.getPoint(), 35, 35, "bot", atractionBots, this, 10, "/images/Tartaruga-avoadoreD.gif");
					}
				} else if (algAstar && currentBot != null) {
					currentBot.move((evt.getX() / cellSpace) * cellSpace + cellSpace / 2, (evt.getY() / cellSpace) * cellSpace + cellSpace / 2);
				} else {
					currentBot = new Bot(evt.getPoint(), 35, 35, "bot", atractionBots, this);
				}
				if (currentGoal != null && heartPosition != null) {
					parent.buttonStart().setEnabled(true);
					if (algAstar) {
						parent.menuItemSave().setEnabled(true);
					}
				}
			} else if (insertingEnemy) {
				currentBot = new Bot(evt.getPoint(), 35, 35, "enemy", false, this);
				//repaint();
			} else if (insertingObstacle) {
				currentObstacle = new Bot(evt.getPoint(), 150, 150, "obstacle", true, this);
				//repaint();
			} else if (insertingLine) {
				currentLine = new RetaCarregada(evt.getX(), evt.getY(), evt.getX() + 1f, evt.getY() + 1f);
				//repaint();
			} else if (insertingTorre) {
				currentTorre = new Torre(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2, this);
			} else if(insertingHeart) {
				if(heartPosition==null) heartPosition = new Heart(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2, this);
				else {
					heartPosition.move(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, 
							((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2);
				}
				if (currentGoal != null && currentBot != null) {
					parent.buttonStart().setEnabled(true);
					if (algAstar) {
						parent.menuItemSave().setEnabled(true);
					}
				}
			} else if (modifyingGrid) {
				Point p = new Point(Math.round(evt.getX() / cellSpace), Math.round(evt.getY() / cellSpace));
				for (int i = 0; i < grid.size(); i++) {
					Atom aux = grid.get(i);
					if (p.x == aux.getX() && p.y == aux.getY()) {
						aux.setColor(colorgrid);
						aux.setCost(currentCost);
						if (!isRunning) {
							repaint();
						}
						return;
					}
				}
				if (colorgrid != null) {
					grid.add(new Atom(colorgrid, p, currentCost));
				}
			}
			else if (chase && movingAgent) {
				agent.xPosition = evt.getX();
				agent.yPosition = evt.getY();
			}
			if (!isRunning) {
				repaint();
			}
		}//GEN-LAST:event_formMousePressed

		private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
			// TODO add your handling code here:
			if (insertingGoal) {
				for (int i = 0; i < botList.size(); i++) {
					Bot bot = botList.get(i);
					if (currentGoal != null && potentialFields) {
						bot.addGoal(currentGoal);
					} else if (chase) {
						bot.addGoal(agent);
					}
				}
			} else if (insertingLine) {
				lineList.add(currentLine);
			} else if (insertingBot && !algAstar) {
				this.addBot(currentBot);
			} else if (insertingTorre) {
				if (myMoney < 10) {
					currentTorre.removeLabel();
					currentTorre = null;
					JOptionPane.showMessageDialog(this, "Você não tem dinheiro para fazer essa operação", "Gekkehond", JOptionPane.ERROR_MESSAGE);
					return;
				} else {
					grid.add(new Atom(getBackground(), new Point(currentTorre.posX/cellSpace, currentTorre.posY/cellSpace), 10000.0f));
					listTorres.add(currentTorre);
					myMoney -= 10;
					parent.setMoneyTExt("$" + myMoney);
					planejaCaminho();
				}
			} else if(insertingHeart) {
				heartPosition.move(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2,
						((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2);
			} else if (insertingEnemy) {
				enemyList.add(currentBot);
			} else if (insertingObstacle) {
				this.addObstacle(currentObstacle);
				if (modifyingGrid) {
					defineObstacle();
				}
			} else if (algAstar) {
				planejaCaminho();
			}
		}//GEN-LAST:event_formMouseReleased

		private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
			// TODO add your handling code here:
			if(algAstar) {
				quadradoMouse.x = (int) (((int) (evt.getPoint().x / cellSpace)) * cellSpace);
				quadradoMouse.y = (int) (((int) (evt.getPoint().y / cellSpace)) * cellSpace);
			}
			if (insertingGoal && currentGoal != null) {
				if (algAstar) {
					currentGoal.updatePosition(new Point(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2));
					if (currentBot != null && currentBot.xPosition >= currentGoal.xPosition) {
						currentBot.changeImage("/images/Tartaruga-avoadoreE.gif");
					} else if (currentBot != null) {
						currentBot.changeImage("/images/Tartaruga-avoadoreD.gif");
					}
				} else {
					currentGoal.updatePosition(new Point(evt.getX(), evt.getY()));
				}
			} else if (insertingBot && currentBot != null) {
				if (algAstar) {
					if (currentGoal != null && evt.getX() >= currentGoal.xPosition) {
						currentBot.changeImage("/images/Tartaruga-avoadoreE.gif");
					} else if (currentGoal != null) {
						currentBot.changeImage("/images/Tartaruga-avoadoreD.gif");
					}

					currentBot.move(( evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ( evt.getY() / cellSpace) * cellSpace + cellSpace / 2);
				} else {
					currentBot.move(evt.getX(),evt.getY());
				}
			} else if (insertingEnemy && currentBot != null) {
				currentBot.move(evt.getX(),evt.getY());
			} else if (insertingObstacle && currentObstacle != null) {
				currentObstacle.move(evt.getX(),evt.getY());
			} else if(insertingHeart) {
				heartPosition.move(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, 
						((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2);
			} else if (insertingTorre && currentTorre != null) {
				currentTorre.move(((int) evt.getX() / cellSpace) * cellSpace + cellSpace / 2, ((int) evt.getY() / cellSpace) * cellSpace + cellSpace / 2);
			} else if (insertingLine) {
				currentLine.setEnd((float) evt.getX(), (float) evt.getY());
			} else if (modifyingGrid) {
				Point p = new Point(Math.round(evt.getX() / cellSpace), Math.round(evt.getY() / cellSpace));
				for (int i = 0; i < grid.size(); i++) {
					Atom aux = grid.get(i);
					if (p.x == aux.getX() && p.y == aux.getY()) {
						aux.setColor(colorgrid);
						aux.setCost(currentCost);
						if (!isRunning) {
							repaint();
						}
						return;
					}
				}
				if (colorgrid != null) {
					grid.add(new Atom(colorgrid, p, currentCost));
				}
			}
			else if (chase && movingAgent) {
				agent.xPosition = evt.getX();
				agent.yPosition = evt.getY();
			}
			if (!isRunning) {
				repaint();
			}
		}//GEN-LAST:event_formMouseDragged

private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved
	if (modifyingGrid) {
		quadradoMouse.x = (int) (((int) (evt.getPoint().x / cellSpace)) * cellSpace);
		quadradoMouse.y = (int) (((int) (evt.getPoint().y / cellSpace)) * cellSpace);

		if (!isRunning) {
			repaint();
		}
	}
// TODO add your handling code here:
}//GEN-LAST:event_formMouseMoved

	public float getCostGrid(int x, int y) {
		for (int i = 0; i < grid.size(); i++) {
			Atom atom = grid.get(i);
			if (x == atom.getX() && y == atom.getY()) {
				return atom.getCost();
			}
		}
		return 1;
	}

	public Atom getAtom(int x, int y) {
		for (int i = 0; i < grid.size(); i++) {
			Atom atom = grid.get(i);
			if (x == atom.getX() && y == atom.getY()) {
				return atom;
			}
		}
		return new Atom(Color.LIGHT_GRAY, new Point(x, y), 1);
	}

	public Dimension getDimensionGrid() {
		return new Dimension(getWidth() % cellSpace > 0 ? getWidth() / cellSpace + 1 : getWidth() / cellSpace, getHeight() % cellSpace > 0 ? getHeight() / cellSpace + 1 : getHeight() / cellSpace);
	}

	public void run() {
		while (true) {
			try {
				if (isRunning) {
					updateForces();
					repaint();
				}
				Thread.sleep(timeToSleep);
			} catch (InterruptedException ex) {
				Logger.getLogger(Scenario.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
	}

	private void drawBots() {
		if (currentBot != null && (insertingBot && !isRunning)) {
			if (!algAstar) {
				currentBot.draw(g2d, showRadar);
			}
		}
		if (algAstar) {
			/*for (Iterator<Bot> it = inimigos.iterator(); it.hasNext();) {
			it.next().draw(g2d, showRadar);
			}*/
		}
		for (int i = 0; i < botList.size(); i++) {
			Bot bot = botList.get(i);
			if (isRunning) {
				if (currentGoal != null && potentialFields) {
					bot.addGoal(currentGoal);
				} else if (chase) {
					bot.addGoal(agent);
				}
				bot.updatePosition();
			}
			bot.draw(g2d, showRadar);
		}
	}

	void drawPosMouse() {
		if (modifyingGrid) {
			g2d.setColor(new Color(0x993311));
			g2d.fillRect(quadradoMouse.x, quadradoMouse.y, cellSpace, cellSpace);
		}
	}

	private void moveBotPositionPath() {
		boolean gameOver = false;
		for (Iterator<Bot> it = inimigos.iterator(); it.hasNext();) {
			Bot nextGuy = it.next();
			if (nextGuy.morreu(listTorres)) {
				nextGuy.removeLabel();
				it.remove();
				myMoney+=2;
				parent.setMoneyTExt("$" + myMoney);
			} else if (nextGuy.path.size() > 0) {

				float fator = 1;
				float oldX =  nextGuy.xPosition;
				float oldY = nextGuy.yPosition;
				Atom atom = nextGuy.path.get(0);
				int atomX = atom.getX() * cellSpace + cellSpace / 2;
				int atomY = atom.getY() * cellSpace + cellSpace / 2;
				boolean eqX = false;
				boolean eqY = false;
				if (oldX - atomX > 0) {
					oldX-=fator;
				} else if (oldX - atomX < 0) {
					oldX+=fator;
				} else {
					eqX = true;
				}

				if (oldY - atomY > 0) {
					oldY-=fator;
				} else if (oldY - atomY < 0) {
					oldY+=fator;
				} else {
					eqY = true;
				}

				if (eqX && eqY) {
					nextGuy.path.remove(0);
				}
				nextGuy.move(oldX, oldY);
			} else {
				//inimigos.remove(nextGuy); // Jah chegou no goal, nao sera mais necessario
				if (nextGuy.getBuscandoSangue() && nextGuy.getVida() > 0) {
					nextGuy.setBuscandoSangue(false);
					nextGuy.incBuscouSangue();
					//astar.setGoal((int) (currentGoal.getXPosition() / cellSpace), (int) (currentGoal.getYPosition() / cellSpace));
					astar.setCurrentPos((int) (nextGuy.xPosition / cellSpace), (int) (nextGuy.yPosition / cellSpace));
					nextGuy.setBestPath(astar.bestPath());
					nextGuy.setVida(vidaInimigo);
					if (nextGuy.xPosition/this.cellSpace >= currentGoal.xPosition / this.cellSpace) {
						nextGuy.changeImage("/images/Tartaruga-avoadoreE.gif");
					} else {
						nextGuy.changeImage("/images/Tartaruga-avoadoreD.gif");
					}
				} else {
					nextGuy.removeLabel();
					it.remove(); // Jah chegou no goal, nao sera mais necessario
					myLife--;
					parent.setLifeTExt("♥" + myLife);
					if (myLife <= 0) {
						gameOver = true;
						break;
					}
				}
			}
		}
		if(gameOver) {
			parent.stopSimulation();
			isRunning = false;
			level=0;
			vidaInimigo = 100;
			myLife = 10;
			myMoney = 100;
			parent.setLvlText("Lvl " + level);
			parent.setMoneyTExt("$" + myMoney);
			parent.setLifeTExt("♥" + myLife);
			for(int i=0;i<inimigos.size(); i++)
				inimigos.get(i).removeLabel();
			inimigos.clear();
			if(currentTorre != null) currentTorre.removeLabel();
			currentTorre = null;

			modifyingGrid = false;
			for(Iterator<Torre> it= listTorres.iterator(); it.hasNext();) {
				Torre t = it.next();
				for(Iterator<Bot> it2= t.listTiros.iterator(); it2.hasNext();) {
					it2.next().removeLabel();
				}
				t.listTiros.clear();
				t.removeLabel();
			}
			listTorres.clear();
			GameOver g = new GameOver(parent);
			Thread t = new Thread(g);
			t.start();
			return;
		}
		else if(inimigos.size()==0) {
			level++;
			parent.setLvlText("Lvl " + level);
			myMoney = (int)((float)myMoney*Math.pow(1.01, (double)level));
			enemiesToGo = (int)(10f*Math.pow(1.01, (double)level));
			vidaInimigo = (int)(vidaInimigo*Math.pow(1.01, (double)level));
		}
	}

	private void drawLines() {
		for (int i = 0; i < lineList.size(); i++) {
			lineList.get(i).draw(g2d);
		}
	}

	public void setLineDensity(float d) {
		RetaCarregada.ajustarDensidadeReta(d);
	}

	private void updateForces() {
		for (int i = 0; i < botList.size(); i++) {
			Bot bot1 = botList.get(i);
			for (int j = i + 1; j < botList.size(); j++) {
				Bot bot2 = botList.get(j);
				bot1.updateRepulseForces(bot2);
			}
		}

		for (int i = 0; i < botList.size(); i++) {
			Bot bot1 = botList.get(i);
			for (int j = 0; j < obstacleList.size(); j++) {
				Bot bot2 = obstacleList.get(j);
				bot1.updateRepulseForces(bot2);
			}
		}

		float[] coordBot = new float[2];
		for (int i = 0; i < botList.size(); i++) {
			Bot bot = botList.get(i);
			coordBot[0] = (float) bot.xPosition;
			coordBot[1] = (float) bot.yPosition;

			for (int j = 0; j < lineList.size(); j++) {
				bot.updateRepulseForces(
								lineList.get(j).forcaAoPonto(coordBot, (float) bot.k_repulsive));
			}
		}
	}

	public void setIsRunning(boolean b) {
		isRunning = b;
	}

	private void drawGoals() {
		if ((potentialFields) && currentGoal != null) {
			if (!algAstar) {
				currentGoal.draw(g2d, showRadar);
			}
		}
	}

	public void setInsertingBot(boolean b) {
		insertingBot = b;
	}

	public void setInsertingObstacle(boolean b) {
		insertingObstacle = b;
	}

	private void drawObstacles() {
		for (int i = 0; i < obstacleList.size(); i++) {
			Bot bot = obstacleList.get(i);
			bot.draw(g2d, showRadar);
		}
		if (currentObstacle != null) {
			currentObstacle.draw(g2d, showRadar);
		}
	}

	private void drawPesosGrid() {
		for (int i = 0; i < grid.size(); i++) {
			Atom atom = grid.get(i);
			if (atom.getCost() != Float.POSITIVE_INFINITY) {
				g2d.setColor(atom.getColor());
				g2d.fillRect(atom.getX() * cellSpace, atom.getY() * cellSpace, cellSpace, cellSpace);
			}
		}
	}

	public void setRadarVisible(boolean showRadar) {
		this.showRadar = showRadar;
	}

	public void setKRepulsiveBots(float force) {
		Bot.k_repulsive = force;
	}

	public void setKAtractionGoal(float force) {
		Bot.k_atractive_goal = force;
	}

	public void setColorGrid(Color color) {
		colorgrid = color;
	}

	public void setCostAtom(float cost) {
		currentCost = cost;
	}

	public void planejaCaminho() {
		if (currentGoal != null) {
			astar.setGoal((int) (currentGoal.getXPosition() / cellSpace), (int) (currentGoal.getYPosition() / cellSpace));
		}
		int i = 0;
		for (Iterator<Bot> it = inimigos.iterator(); it.hasNext();) {
			Bot inimigo = it.next();
			astar.setCurrentPos((int) (inimigo.xPosition / cellSpace), (int) (inimigo.yPosition / cellSpace));
			inimigo.setBestPath(astar.bestPath());
			i++;
		}
		showRadar = false;
	}

	class GameOver implements Runnable{

		private JFrame jf;
		public GameOver(JFrame jf){
			this.jf = jf;
		}
		public void run() {
			JOptionPane.showMessageDialog(jf, "Game Over!", "Gekkehond", JOptionPane.ERROR_MESSAGE);
		}

	}
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
